using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace Module
{
    public class CDESecurity
    {
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        internal static string UserMd5(string str)
        {
            string cl = "CDE" + str + "EDC";
            StringBuilder buf = new StringBuilder();
            MD5 md5 = MD5.Create();

            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
            for (int i = 0; i < s.Length; i++)
            {
                if ((s[i] & 0xff) < 0x10)
                {
                    buf.Append("0");
                }
                buf.Append(s[i].ToString("X"));

            }
            return buf.ToString();
        }

        private static string _UserDESKey;
        private static ICryptoTransform _CEncryptor;
        private static ICryptoTransform _CDecryptor;
        public static string UserDESKey
        {
            get
            {
                return _UserDESKey;
            }
            set 
            {
                _UserDESKey = value;
                if (Cit.CDE.Net.Module.Commons.CDEConstants.IsEmpty(UserDESKey))
                {
                    if (_CEncryptor != null)
                    {
                        _CEncryptor.Dispose();
                        _CEncryptor = null;
                    }
                    if (_CDecryptor != null)
                    {
                        _CDecryptor.Dispose();
                        _CDecryptor = null;
                    }
                }
                else
                {
                    _UserDESKey = _UserDESKey + "00000000";
                    byte[] keyBytes = new byte[8];
                    byte[] UTF8Key = Encoding.UTF8.GetBytes(UserDESKey.Substring(0, 8));
                    for (int i = 0; i < 8; i++)
                    {
                        keyBytes[i] = UTF8Key[i];
                    }
                    byte[] keyIV = keyBytes;

                    DESCryptoServiceProvider objDes = new DESCryptoServiceProvider();
                    _CEncryptor = objDes.CreateEncryptor(keyBytes, keyIV);
                    _CDecryptor = objDes.CreateDecryptor(keyBytes, keyIV);
                }
            }
        }
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string UserDESEncrypt(string str)
        {
            if (Cit.CDE.Net.Module.Commons.CDEConstants.IsEmpty(UserDESKey))
            {
                return str;
            }

            byte[] inputByteArray = Encoding.UTF8.GetBytes(str);

            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, _CEncryptor, CryptoStreamMode.Write);

            byte[] cipherbytes;
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.Close();
            cipherbytes = ms.ToArray();
            ms.Close();

            string rnt = Cit.CDE.Net.Module.Commons.ConversionUtils.ByteToHex(cipherbytes);

            return rnt;
        }
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string UserDESDecryptor(string str)
        {
            if (Cit.CDE.Net.Module.Commons.CDEConstants.IsEmpty(UserDESKey))
            {
                return str;
            }
            byte[] inputByteArray = Cit.CDE.Net.Module.Commons.ConversionUtils.HexToByte(str);
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, _CDecryptor, CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Encoding.UTF8.GetString(mStream.ToArray());

        }

        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static object getDesEncryptValue(object value, string encrypt_flag)
        {
            if (!"2".Equals(encrypt_flag) || value == null)
            {
                return value;
            }

            //des
            return UserDESEncrypt((string)value);
        }

        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static object getDesDecryptorValue(object value, string encrypt_flag)
        {
            if (!"2".Equals(encrypt_flag) || value == null)
            {
                return value;
            }

            //des
            return UserDESDecryptor((string)value);
        }
    }
}
